/**
 * Copyright (c) 2022 Yansen Zhang
 * wxcomponent is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
**/

package authorization

import (
	"errors"
	"net/url"
	"strconv"

	"gitee.com/yansen_zh/wxcomponent/utils/request"
)

// AuthLinkParam 构建授权链接入参
type AuthLinkParam struct {
	ComponentAppId string
	PreAuthCode    string

	// RedirectUri 不需要转码
	RedirectUri string
	AuthType    int
	BizAppId    string
}

const (
	componentloginpage = "https://mp.weixin.qq.com/cgi-bin/componentloginpage"
	bindcomponent      = "https://mp.weixin.qq.com/safe/bindcomponent"
)

// GetPCAuthLink 构建PC端授权链接
func GetPCAuthLink(param AuthLinkParam) (*url.URL, error) {
	return GetAuthLink("PC", param)
}

// GetH5AuthLink 构建H5端授权链接
func GetH5AuthLink(param AuthLinkParam) (*url.URL, error) {
	return GetAuthLink("H5", param)
}

// GetAuthLink 构建授权链接
func GetAuthLink(client string, param AuthLinkParam) (*url.URL, error) {
	isH5 := client == "H5"

	if param.ComponentAppId == "" {
		return nil, errors.New("构建授权链接 第三方平台的 appid 不能为空")
	}

	if param.PreAuthCode == "" {
		return nil, errors.New("构建授权链接 预授权码 不能为空")
	}

	if param.RedirectUri == "" {
		return nil, errors.New("构建授权链接 回调 URI 不能为空")
	}

	if param.AuthType < 1 || param.AuthType > 3 {
		param.AuthType = 3
	}

	queryParams := url.Values{}
	if isH5 {
		queryParams.Set("action", "bindcomponent")
		queryParams.Set("no_scan", "1")
	}
	queryParams.Set("component_appid", param.ComponentAppId)
	queryParams.Set("pre_auth_code", param.PreAuthCode)
	queryParams.Set("redirect_uri", param.RedirectUri)
	// auth_type、biz_appid 两个字段互斥
	if param.BizAppId != "" {
		queryParams.Set("biz_appid", param.BizAppId)
	} else {
		queryParams.Set("auth_type", strconv.Itoa(param.AuthType))
	}

	apiUrl := componentloginpage
	if isH5 {
		apiUrl = bindcomponent
	}
	u, err := request.ParseURL(apiUrl, &queryParams)
	if err != nil {
		return nil, err
	}

	if isH5 {
		u.Fragment = "wechat_redirect"
	}

	return u, nil
}
